﻿using System;
using System.Collections.Generic;
using System.IO;
using Windows.Graphics.Imaging;


namespace DNFImagePacks2Manager.NPK
{
    public abstract class IMGFile
    {
        public IMGHeader Header { get; set; }
        public List<ImageFile> Images { get; set; } = [];

        public IMGFile(IMGHeader imgHeader) {
            Header = imgHeader;
        }

        public static IMGFile? ReadIMGFile(BinaryReader reader)
        {
            IMGFile? imgFile = null;
            IMGHeader imgHeader = new(reader);
            switch (imgHeader.Version)
            {
                case 2:
                    imgFile = new IMGV2File(reader, imgHeader);
                    break;
                case 5:
                    imgFile = new IMGV5File(reader, imgHeader);
                    break;
                case 4:
                case 6:
                    imgFile = new IMGV4File(reader, imgHeader);
                    break;
            }
            return imgFile;
        }

        public static IMGFile? ReadFromByte(byte[] fileBytes)
        {
            IMGFile? imgFile = null;
            try
            {
                using var stream = new MemoryStream(fileBytes);
                using var reader = new BinaryReader(stream);
                imgFile = ReadIMGFile(reader);
            }
            catch (Exception) { }
            return imgFile;
        }

        public byte[] GetIndexsBytes()
        {
            List<byte> bytes = []; 
            foreach (var image in Images)
            {
                bytes.AddRange(image.GetIndexBytes());
            }
            return [.. bytes];
        }

        public byte[] GetHeaderBytes(int indexsSize)
        {
            Header.Count = Images.Count;
            Header.Size = indexsSize;
            return Header.GetBytes();
        }

        public byte[] GetHeaderBytes()
        {
            return GetHeaderBytes(GetIndexsBytes().Length);
        }

        public virtual bool SetImage(int index, ImageFile image)
        {
            if(index < Images.Count)
            {
                if (image is ImagePointerFile pointerImage)
                {
                    Images[index] = pointerImage;
                    return true;
                }
                return false;
            }
            else
            {
                return false;
            }
        }

        public virtual SoftwareBitmap? GetPreviewImage(int index, bool ignorePointer = true)
        {
            if (index < Images.Count)
            {
                ImageFile image = Images[index];
                if (image is ImagePointerFile pointerImage)
                {
                    if (ignorePointer || pointerImage.Pointer == index)
                    {
                        return null;
                    }
                    else
                    {
                        return GetPreviewImage(pointerImage.Pointer, ignorePointer);
                    }
                }
            }
            return null;
        }

        public abstract byte[] GetBytes();
    }
}
